/////////////////////////////////////////////////////////////////////////////
// Name:        tts_sapi.h
// Purpose:     A wxWidgets wrapper around SAPI
// Author:      Julian Smart
// Modified by: 
// Created:     2009-02-10
// RCS-ID:      
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_TTS_SAPI_
#define _WX_TTS_SAPI_

/*
 * Includes
 */

#include "tts/tts.h"

/*
 * Styles and types
 */

// SAPI-specific properties

/**
    @class wxTTSSapiHandler
    
    @category{tts}
 */

class wxTTSSapiData;
class wxTTSSapiHandler: public wxTTSHandler
{    
    DECLARE_DYNAMIC_CLASS( wxTTSSapiHandler )

public:
// Constructors

    wxTTSSapiHandler();
    ~wxTTSSapiHandler();

// Operations

    /// Member initialisation
    void Init();

    /// Initialize the engine. Can call multiple times.
    virtual bool Initialize();

    /// Clean up the engine. Can call multiple times.
    virtual bool Uninitialize();

    /// Speak the text
    virtual bool Speak(const wxString& text, int options = wxTTS_SPEAK_ASYNC);

    /// Speak the file
    virtual bool SpeakFile(const wxString& filename, int options = wxTTS_SPEAK_ASYNC, const wxString& waveFilename = wxEmptyString);

    /// Speak the text or file
    virtual bool DoSpeak(const wxString& textOrFilename, bool isFilename, int options = wxTTS_SPEAK_ASYNC, const wxString& waveFilename = wxEmptyString);

    /// Is it speaking?
    virtual bool IsSpeaking() const;

    /// Is it paused?
    virtual bool IsPaused() const;

    /// Stop speaking
    virtual bool Stop();

    /// Pause
    virtual bool Pause();

    /// Resume
    virtual bool Resume();

    /// Skip forward or backward the given number of items. A positive value skips forward,
    /// and a negative value skips back. A value of zero skips to the start of the item.
    /// itemType may be ignored by some or all engines.
    virtual bool Skip(int toSkip, wxTTSSkipType itemType = wxTTS_SkipSentence);

    /// Can we skip right now?
    virtual bool CanSkip() const;

    /// Get a list of the available voices
    virtual wxArrayString GetAvailableVoices() const;

    /// Can these two voices be used together? Pass an empty string to the voice parameters
    /// to find out whether the engine in general supports simultaneous voices. Pass voice names
    /// to find out if these voices can be used simultaneously, when using the given engine.
    /// The voice names can be the same.
    virtual bool VoicesAreCompatible(const wxString& voice1, const wxString& voice2) const;

    /// Get a list of the available voice variants
    virtual wxArrayString GetAvailableVoiceVariants() const;

    /// Does this handler have the specified capability?
    virtual bool HasCapability(wxTTSCapability capability) const;

    virtual int GetMinSpeed() const { return -10; }
    virtual int GetMaxSpeed() const { return 10; }
    virtual int GetMinVolume() const { return 0; }
    virtual int GetMaxVolume() const { return 100; }

    // Native pitch control is a multiplication factor,
    // but convert to percentage for wxTextToSpeech.
    // 50 would be the default.
    virtual int GetMinPitch() const { return 0; }
    virtual int GetMaxPitch() const { return 100; }

    /// Get the default voice
    virtual wxString GetDefaultVoice() const;

    /// Get the default voice variant
    virtual wxString GetDefaultVoiceVariant() const;

    /// Get a list of the available voices, given the voices directory
    static wxArrayString GetAvailableVoicesForDir(const wxString& voicesDir);

    /// Create transformation options from handler's properties
    virtual int CreateTransformerOptions(int mandatoryOptions = 0) const;

    /// Get data
    wxTTSSapiData* GetData() const { return m_data; }

    /// Implementation: callback
    void Callback();
    void Yield();

    /// Call this to set an array of match strings that are used to determine whether voices can be used
    /// simultaneously (using VoicesAreCompatible). Each string will be used to match against the actual voice name,
    /// so for example "eSpeak" will match against all eSpeak voices.
    static void SetSimultaneousVoiceExclusions(const wxArrayString& exclusions) { sm_simultaneousVoiceExclusions = exclusions; }
    static const wxArrayString& GetSimultaneousVoiceExclusions() { return sm_simultaneousVoiceExclusions; }
protected:

    wxTTSSapiData* m_data;
    static wxArrayString sm_simultaneousVoiceExclusions;
};

#endif
    // _WX_TTS_SAPI_
